using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebTools.UI.WebControls
{
	[ToolboxItem(false)]
	public abstract class WebControlLabel<T> : CompositeControl, IPostBackDataHandler, IEditableTextControl, ITextControl where T : WebControl
	{
		protected Label InnerLabel = new Label();
		protected T InnerWebControl = null;

		protected WebControlLabel()
		{
			InnerWebControl = Activator.CreateInstance<T>();
		}

		/// <summary>
		/// Creates the child label and web controls that represent this WebControlLanel.
		/// </summary>
		protected override void CreateChildControls()
		{
			this.Controls.Clear();

			this.InnerLabel.ID = String.Concat(this.ID, "_Label");
			this.InnerLabel.ApplyStyle(this.ControlStyle);
			this.InnerLabel.CssClass = this.LabelCssClass;

			this.Controls.Add(this.InnerLabel);

			this.SetCustomProperties(this.InnerWebControl);
			this.InnerWebControl.ID = this.ID;
			this.InnerWebControl.ApplyStyle(this.ControlStyle);

			ITextControl txt = this.InnerWebControl as ITextControl;
			if (txt != null)
			{
				txt.Text = this.Text;
			}

			this.Controls.Add(this.InnerWebControl);

			base.ChildControlsCreated = true;
		}

		/// <summary>
		/// Override this method to add custom properties to controls such as max length to textbox controls, etc.
		/// </summary>
		/// <param name="control">The control specified as the generic T argument.</param>
		/// <remarks>
		/// <para>
		/// If the WebControl set as the T argument of the class does not provide a Text property handle the Text 
		/// implementation by overriding the Text property or within the SetCustomProperties method.
		/// </para>
		/// </remarks>
		protected virtual void SetCustomProperties(T control)
		{
		}

		#region IPostBackDataHandler Members

		public virtual bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
		{
			string text = this.Text;
			string text2 = postCollection[postDataKey];
			if (!text.Equals(text2, StringComparison.Ordinal))
			{
				this.Text = text2;
				return true;
			}
			return false;
		}

		public virtual void RaisePostDataChangedEvent()
		{
			this.OnTextChanged(EventArgs.Empty);
		}

		#endregion

		#region IEditableTextControl Members

		public event EventHandler TextChanged;

		protected void InternalTextChanged(object sender, EventArgs e)
		{
			this.OnTextChanged(e);
		}
		protected void OnTextChanged(EventArgs e)
		{
			if (this.TextChanged != null)
			{
				this.TextChanged(this.InnerWebControl, e);
			}
		}
		#endregion

		#region Render Methods
		/// <summary>
		/// If overridden in a derived class ensure that base.OnPreRender is called to properly set child control values 
		/// and LabelMode state.
		/// </summary>
		/// <param name="e"></param>
		protected override void OnPreRender(EventArgs e)
		{
			this.InnerLabel.Visible = this.LabelMode;
			this.InnerWebControl.Visible = (!this.LabelMode);

			if (this.LabelMode)
			{
				this.InnerLabel.Text = this.Text;
			}

			base.OnPreRender(e);
		}
		public override void RenderBeginTag(HtmlTextWriter writer)
		{
			// Not rendering a begin or end tag.
		}
		public override void RenderEndTag(HtmlTextWriter writer)
		{
			// Not rendering a begin or end tag.
		}
		#endregion

		#region Properties
		[Bindable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets the render mode of the control.")]
		[DefaultValue(false)]
		public bool LabelMode
		{
			get
			{
				object obj = ViewState["LabelMode"];
				if (obj != null)
				{
					return (bool)obj;
				}
				return false;
			}
			set { ViewState["LabelMode"] = value; }
		}

		[DefaultValue("")]
		[Localizable(true)]
		[Bindable(true, BindingDirection.TwoWay)]
		[Category("Appearance")]
		[Description("The text that will be displayed in either the textbox or label when the control is rendered.")]
		[PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)]
		public virtual string Text
		{
			get
			{
				string text = (string)this.ViewState["Text"];
				if (text != null)
				{
					return text;
				}
				return String.Empty;
			}
			set
			{
				this.ViewState["Text"] = value;
			}
		}

		[Bindable(true)]
		[Category("Style")]
		[Description("Sets the Css Class style for the label control when in label mode.")]
		[DefaultValue(false)]
		public string LabelCssClass
		{
			get
			{
				string text = (string)this.ViewState["LabelCssClass"];
				if (text != null)
				{
					return text;
				}
				return String.Empty;
			}
			set
			{
				this.ViewState["LabelCssClass"] = value;
			}
		}
		#endregion
	}
}
